<?php

namespace helper\ali;

use AlipayUserInfoShareRequest;
use AopCertClient;
use AlipayUserInfoAuthRequest;
use AlipaySystemOauthTokenRequest;

require_once __DIR__ . '/sdk/aop/AopCertClient.php';
require_once __DIR__ . '/sdk/aop/request/AlipaySystemOauthTokenRequest.php';
require_once __DIR__ . '/sdk/aop/request/AlipayUserInfoAuthRequest.php';
require_once __DIR__ . '/sdk/aop/request/AlipayUserInfoShareRequest.php';

class Alipay
{
    private array $config;

    public function __construct($config)
    {
        $this->config = [
            'appid' => $config['appid'],
            'notify_url' => $config['notify_url'] ?? '',
            'private_key' => $config['private_key'],// 开发者私钥(应用私钥)
            'payer' => $config['payer'] ?? '',
            'app_cert_path' => $config['app_cert_path'],
            'alipay_cert_path' => $config['alipay_cert_path'],
            'root_cert_path' => $config['root_cert_path'],
        ];
    }

    private function aop()
    {
        $aop = new AopCertClient ();
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->appId = $this->config['appid'];
        $aop->rsaPrivateKey = $this->config['private_key'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset='utf-8';
        $aop->format='json';
        $aop->isCheckAlipayPublicCert = true;//是否校验自动下载的支付宝公钥证书，如果开启校验要保证支付宝根证书在有效期内
        $aop->appCertSN = $aop->getCertSN($this->config['app_cert_path']);//调用getCertSN获取证书***
        $aop->alipayrsaPublicKey = $aop->getPublicKey($this->config['alipay_cert_path']);//调用getPublicKey从支付宝公钥证书中提取公钥
        $aop->alipayRootCertSN = $aop->getRootCertSN($this->config['root_cert_path']);//调用getRootCertSN获取支付宝根证书***
        return $aop;
    }

    /**
     * App支付宝登录
     * 1.开发者中心创建应用
     * 授权回调地址是用户授权结束后回跳的地址，用于接收用户授权的结果，如：授权、拿到auth_code，便于后续换取授权令牌（access_token）等
     * 授权回调地址错误:对不起,访问出错了
     *
     * 0.授权请求参数
     * scope:口权限值，目前只支持auth_user（获取用户信息、网站支付宝登录）、auth_base（用户信息授权）、auth_ecard（商户会员卡）、auth_invoice_info（支付宝闪电开票）、auth_puc_charge（生活缴费）五个值;多个scope时用”,”分隔
     * redirect_uri:授权回调地址，是经过URLENCODE转义 的url链接（url必须以http或者https开头）
     * state:商户自定义参数，用户授权后，重定向到redirect_uri时会原样回传给商户
     *
     * 返回数据
     * resultStatus=9000
     * memo="处理成功"
     * result="success=true&auth_code=d9d1b5acc26e461dbfcb6974c8ff5E64&result_code=200 &user_id=2088003646494707"
     * 仅当resultStatus为“9000”且result_code为“200”时，代表授权成功。auth_code表示授权成功的授码
     **/

    /**
     * APP登录
     *
     * @param string $scope auth_base(静默)， auth_userinfo
     * @return string
     */
    public function getCode(string $redirect_uri = '', string $scope = 'auth_base', $state = 'alipay'): string
    {
        $config = $this->config;
        $redirect_uri = urlencode($redirect_uri);
        $url = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";
        //1.URL拼接与scope
        return $url . "?app_id={$config['appid']}&scope={$scope}&redirect_uri={$redirect_uri}&state={$state}";
        //2.获取auth_code
    }

    /**
     * 换取授权访问令牌
     * grant_type:值为authorization_code时，代表用code换取；值为refresh_token时，代表用refresh_token换取
     * code:授权码，用户对应用授权后得到。
     * refresh_token:刷刷新令牌，上次换取访问令牌时得到。见出参的refresh_token字段
     */
    public function systemOauthToken($code)
    {
        $request = new AlipaySystemOauthTokenRequest ();
        $request->setGrantType("authorization_code");
        $request->setCode($code);
        //$request->setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
        $result = $this->aop()->execute ( $request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            return $result->$responseNode;
        } else {
            return $result->$responseNode;
        }
    }

    /**
     * App支付宝登录
     * 用户登录授权
     * scopes:目前只支持auth_user和auth_base两个值
     * state:商户自定义参数
     */
    public function userInfoAuth()
    {
        $request = new AlipayUserInfoAuthRequest ();
        $request->setBizContent("{" .
            "      \"scopes\":[" .
            "        \"auth_base\"" .
            "      ]," .
            "\"state\":\"init\"" .
            "  }");
        return $this->aop()->pageExecute ( $request);
    }

    /**
     * 用户信息共享接口
     */
    public function userInfoShare($accessToken)
    {
        $request = new AlipayUserInfoShareRequest ();
        $result = $this->aop()->execute ( $request , $accessToken );

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            return $result->$responseNode;
        } else {
            return $result->$responseNode;
        }
    }
}